﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CSP.Bll.CommonBll;
using CSP.Bll.IObjectBlls;
using CSP.Dao.IObjectDaos.CSP;
using CSP.Common.Factories;
using CSP.Dao;
using CSP.Model.CSP;
using System.Collections.ObjectModel;
using CSP.Model.CSPEnum;
using CSP.Bll.DTO.Order;

namespace CSP.Bll.ObjectBlls
{
    public class OrderBll : CSPCommonBll, IOrderBll
    {

        /// <summary>
        /// 缓存键值
        /// </summary>
        private const string CACHEKEY = "Order_";

        private CSPDaoFactory _factory;

        private IOrderDao _orderDao;

        public OrderBll()
        {
            _factory = CSPDaoFactory.GetInstance();
            _cacheProvider = CachedProviderFactory.GetMemCachedProvider();
            _orderDao = _factory.GetOrderDao();
        }

        public ICollection<Model.CSP.Order> FindByOrderUser(string userName, DateTime startTime, DateTime endTime, int pageIndex, int pageSize, out int pageCount)
        {
            string cacheKey = CACHEKEY + "OrderUser_" + userName + startTime.ToString("yyyyMMddhhmmss") + endTime.ToString("yyyyMMddhhmmss") + "_" + pageIndex.ToString() + "_" + pageSize;
            string cacheKeyCount = CACHEKEY + "OrderUser_" + userName + startTime.ToString("yyyyMMddhhmmss") + endTime.ToString("yyyyMMddhhmmss") + "_" + pageIndex.ToString() + "_" + pageSize + "Count";

            //依赖性Key 值，每个用户都会有一个依赖性Key值
            string cacheKeyUser = CACHEKEY + userName;

            ICollection<Order> orders = _cacheProvider.GetData<Collection<Order>>(cacheKey);
            pageCount = _cacheProvider.GetData<int>(cacheKeyCount);

            if (orders == null)
            {
                orders = _orderDao.FindByOrderUser(userName, startTime, endTime, pageIndex, pageSize, out pageCount);

                DateTime failureTime = DateTime.Now.AddMinutes(10);
                _cacheProvider.AddData(cacheKeyUser, userName, failureTime);
                _cacheProvider.AddData(cacheKey, orders, failureTime, new string[] { cacheKeyUser });
                _cacheProvider.AddData(cacheKeyCount, pageCount, failureTime, new string[] { cacheKeyUser });
            }
            return orders;
        }

        public ICollection<Model.CSP.Order> FindByServiceUser(string userName, DateTime startTime, DateTime endTime, int pageIndex, int pageSize, out int pageCount)
        {
            string cacheKey = CACHEKEY + "ServiceUser_" + userName + startTime.ToString("yyyyMMddhhmmss") + endTime.ToString("yyyyMMddhhmmss") + "_" + pageIndex.ToString() + "_" + pageSize;
            string cacheKeyCount = CACHEKEY + "ServiceUser_" + userName + startTime.ToString("yyyyMMddhhmmss") + endTime.ToString("yyyyMMddhhmmss") + "_" + pageIndex.ToString() + "_" + pageSize + "Count";
            //依赖性Key 值，每个用户都会有一个依赖性Key值
            string cacheKeyUser = CACHEKEY + userName;

            ICollection<Order> orders = _cacheProvider.GetData<Collection<Order>>(cacheKey);
            pageCount = _cacheProvider.GetData<int>(cacheKeyCount);

            if (orders == null)
            {
                orders = _orderDao.FindByOrderUser(userName, startTime, endTime, pageIndex, pageSize, out pageCount);

                //定义失效时间
                DateTime failureTime = DateTime.Now.AddMinutes(10);
                _cacheProvider.AddData(cacheKeyUser, userName, failureTime);
                _cacheProvider.AddData(cacheKey, orders, failureTime, new string[] { cacheKeyUser });
                _cacheProvider.AddData(cacheKeyCount, pageCount, failureTime, new string[] { cacheKeyUser });
            }
            return orders;
        }

        public Model.CSP.Order GetDataByOrderNumber(string orderNumber)
        {
            string cacheKey = CACHEKEY + orderNumber.ToString();
            Order order = _cacheProvider.GetData<Order>(cacheKey);
            if (order == null)
            {
                order = _orderDao.GetDataByOrderNumber(orderNumber);
                _cacheProvider.AddData(cacheKey, order);
            }
            return order;
        }

        [Obsolete("此方法已经废弃", true)]
        public ICollection<Model.CSP.Order> GeDatatByIds(int[] Ids)
        {
            //To Do
            throw new NotImplementedException();
        }

        [Obsolete("此方法已经废弃", true)]
        public void Add(Model.CSP.Order obj)
        {
            _orderDao.Add(obj);


            //依赖性Key 值，每个用户都会有一个依赖性Key值
            string cacheKeyOrderUserName = CACHEKEY + obj.OrderUserName;
            string cacheKeyServiceUserName = CACHEKEY + obj.ServiceUserName;

            //删除依赖性缓存
            _cacheProvider.Remove(cacheKeyOrderUserName);
            _cacheProvider.Remove(cacheKeyServiceUserName);

        }

        [Obsolete("此方法已经废弃", true)]
        public void Update(Model.CSP.Order obj)
        {
            string cacheKey = CACHEKEY + obj.OrderNumber.ToString();
            _orderDao.Update(obj);

            _cacheProvider.Remove(cacheKey);
        }

        [Obsolete("此方法已经废弃", true)]
        public void DeleteById(int id)
        {
            //To Do
            throw new NotImplementedException();
        }

        public void RefreshCache()
        {

        }


        public int FindCountByServiceInfoOrderNumber(int serviceInfoId)
        {
            return _orderDao.FindCountByServiceInfoId(serviceInfoId);
        }


        /// <summary>
        /// 创建订单
        /// </summary>
        /// <param name="order"></param>
        /// <returns></returns>
        public CreateOrderResponseDTO CreateOrder(Order order)
        {
            CreateOrderResponseDTO response = new CreateOrderResponseDTO();

            IServiceInfoDao _serviceInfoDao = _factory.GetServiceInfoDao();
            ServiceInfo serviceInfo = _serviceInfoDao.GetDataById(order.ServiceInfoId);
            if (serviceInfo == null)
            {
                response.Status = CreateOrderStatus.None;
                return response;
            }
            if (Convert.ToInt32(serviceInfo.status) != (int)ServiceInfoStatus.OnLine)
            {
                response.Status = CreateOrderStatus.OffLined;
                return response;
            }
            if (order.StudentInfoes.Count > serviceInfo.SurplusEnjoyCount)
            {
                response.Status = CreateOrderStatus.ServiceShortage;
                return response;
            }

            //创建订单
            order.OrderNumber = CreateNewOrderMember();
            order.ServiceUserName = serviceInfo.username;
            //order.UnitCount = order.StudentInfoes.Count;
            order.CreateTime = DateTime.Now;
            order.status = (int)OrderStatus.Waiting;
            order.ServiceTitle = serviceInfo.title;
            order.TotalPrice = serviceInfo.Price * order.StudentInfoes.Count;
            order.OrderRemind = GetOrderRemindByReminStatus(OrderRemindStatus.ServiceCooperationConfirm);
            _orderDao.Add(order);

            response.OrderNumber = order.OrderNumber;
            response.Status = CreateOrderStatus.SuccessFully;

            //处理处理库存
            serviceInfo.SurplusEnjoyCount -= order.StudentInfoes.Count;
            _serviceInfoDao.Update(serviceInfo);

            return response;

        }

        /// <summary>
        /// 生成新订单号
        /// </summary>
        /// <returns></returns>
        private string CreateNewOrderMember()
        {
            DateTime now = DateTime.Now;
            string result = now.Year.ToString() + now.Month.ToString() + now.Day.ToString() + now.Hour.ToString() + now.Minute.ToString() + now.Second.ToString() + now.Millisecond.ToString();
            return result;
        }

        /// <summary>
        /// 根据订单提醒状态 返回订单
        /// </summary>
        /// <param name="cemindStatus"></param>
        /// <returns></returns>
        private OrderRemind GetOrderRemindByReminStatus(OrderRemindStatus cemindStatus)
        {
            OrderRemind result = new OrderRemind
            {
                RemindStatus = (int)cemindStatus,
                LostTime = DateTime.Now.AddDays(7),
                CreateTime = DateTime.Now

            };
            return result;
        }

        public List<string> FindOrderNumbersByConsumeUser(string consumeUserName)
        {
            return _orderDao.FindOrderNumbersByConsumeUser(consumeUserName);
        }

        public List<string> FindOrderNumbersByServiceUser(string serviceUserName)
        {
            return _orderDao.FindOrderNumbersByServiceUser(serviceUserName);
        }

        public List<string> FindOrderNumbersByConsumeUserNameAndStartTimeAndEndTime(string consumeUserName, DateTime startTime, DateTime endTime)
        {
            return _orderDao.FindOrderNumbersByConsumeUserNameAndStartTimeAndEndTime(consumeUserName, startTime, endTime);
        }

        public List<string> FindOrderNumbersByServiceUserNameAndStartTimeAndEndTime(string serviceUserName, DateTime startTime, DateTime endTime)
        {
            return _orderDao.FindOrderNumbersByServiceUserNameAndStartTimeAndEndTime(serviceUserName, startTime, endTime);
        }

        public Order GetByOrderNumberAndConsumeUser(string orderNumber, string consumeUserName)
        {
            return _orderDao.GetByOrderNumberAndConsumeUser(orderNumber, consumeUserName);
        }

        public Order GetByOrderNumberAndServiceUser(string orderNumber, string serviceUserName)
        {
            return _orderDao.GetByIdAndServiceUser(orderNumber, serviceUserName);
        }

        public List<string> FindOrderNumbersByConsumeUserAndStatus(string consumeUser, OrderStatus status)
        {
            return _orderDao.FindOrderNumbersByConsumeUserAndStatus(consumeUser, status);
        }

        public List<string> FindOrderNumbersByServiceUserAndStatus(string serviceUser, OrderStatus status)
        {
            return _orderDao.FindOrderNumbersByServiceUserAndStatus(serviceUser, status);
        }

        public ICollection<Order> GetByOrderNumbers(List<string> orderNumbers, int pageIndex, int pageSize)
        {
            return _orderDao.GetByOrderNumbers(orderNumbers, pageIndex, pageSize);
        }

        public Order UpdateServiceStatus(string orderNumber, string serviceUserName, OrderStatus orderStatus)
        {
            Order order = _orderDao.GetByIdAndServiceUser(orderNumber, serviceUserName);
            if (order != null)
            {
                if (orderStatus == OrderStatus.Canceled && (OrderStatus)order.status != OrderStatus.Waiting)
                {
                    throw new Exception("订单状态不等于创建，不允许服务者取消订单");
                }
                else if (orderStatus == OrderStatus.ServiceConfirm && (OrderStatus)order.status != OrderStatus.Waiting)
                {
                    throw new Exception("订单状态不等于创建，不允许服务者确认预约");
                }
                order.status = (int)orderStatus;
            }
            //如果是服务者提交确认
            if (orderStatus == OrderStatus.ServiceConfirm)
            {
                //提醒消费者确认
                order.OrderRemind = GetOrderRemindByReminStatus(OrderRemindStatus.ConsumeCooperationConfirm);
            }
            //如果取消订单
            else if (orderStatus == OrderStatus.Canceled)
            {
                order.OrderRemind = GetOrderRemindByReminStatus(OrderRemindStatus.ServiceCanceled);
            }

            return order;
        }

        public Order UpdateConsumeStatus(string orderNumber, string consumeUserName, OrderStatus orderStatus)
        {
            Order order = _orderDao.GetByIdAndServiceUser(orderNumber, consumeUserName);

            if (order != null)
            {
                if (orderStatus == OrderStatus.Canceled && (OrderStatus)order.status != OrderStatus.Waiting && (OrderStatus)order.status != OrderStatus.ServiceConfirm)
                {
                    throw new Exception("订单状态不等于创建,或者服务者确认状态，不允许取消订单");
                }
                else if (orderStatus == OrderStatus.ConsumeConfirm && (OrderStatus)order.status != OrderStatus.ServiceConfirm)
                {
                    throw new Exception("如果订单状态服务者没有确认，不允许消费者确认预约");
                }
                order.status = (int)orderStatus;
            }


            if (orderStatus == OrderStatus.ConsumeConfirm)
            {
                //提醒双方待评价
                order.OrderRemind = GetOrderRemindByReminStatus(OrderRemindStatus.ServiceCooperationConfirm);
            }
            //如果取消订单
            else if (orderStatus == OrderStatus.Canceled)
            {
                order.OrderRemind = GetOrderRemindByReminStatus(OrderRemindStatus.ServiceCanceled);
            }
            return order;
        }


        public List<string> FindByConsumeUserAndSearchValue(string consumeUser, string searchValue)
        {
            return _orderDao.FindByConsumeUserAndSearchValue(consumeUser, searchValue);
        }

        public List<string> FindByServiceUserAndSearchValue(string serviceUser, string searchValue)
        {
            return _orderDao.FindByConsumeUserAndSearchValue(serviceUser, searchValue);
        }

        [Obsolete("此方法已经废弃", true)]
        public Order GetDataById(int id)
        {
            throw new NotImplementedException();
        }


        public Order CancelOrderAsService(string orderNumber, string serviceUserName)
        {
            Order order = _orderDao.GetByIdAndServiceUser(orderNumber, serviceUserName);

            if (order != null)
            {
                if ((OrderStatus)order.status != OrderStatus.Waiting)
                {
                    throw new Exception("订单状态不等于创建，不允许取消订单");
                }
                order.status = (int)OrderStatus.Canceled;
            }

            //提醒消费者已经将订单取消
            order.OrderRemind = GetOrderRemindByReminStatus(OrderRemindStatus.ServiceCanceled);
            _orderDao.Update(order);
            return order;
        }

        public Order CancelOrderAsConsume(string orderNumber, string consumeUserName)
        {
            Order order = _orderDao.GetByIdAndServiceUser(orderNumber, consumeUserName);

            if (order != null)
            {
                if ((OrderStatus)order.status != OrderStatus.Waiting && (OrderStatus)order.status != OrderStatus.ServiceConfirm)
                {
                    throw new Exception("订单状态不等于创建或者服务者确认状态时，不允许取消订单");
                }
                order.status = (int)OrderStatus.Canceled;
            }

            //提醒服务者已经将订单取消
            order.OrderRemind = GetOrderRemindByReminStatus(OrderRemindStatus.ServiceCanceled);
            _orderDao.Update(order);

            return order;
        }

        public Order ConfirmOrderAsService(string orderNumber, string serviceUserName, DateTime confirmStartDate, DateTime confirmEndDate)
        {
            Order order = _orderDao.GetByIdAndServiceUser(orderNumber, serviceUserName);

            if (order != null)
            {

                if ((OrderStatus)order.status != OrderStatus.Waiting)
                {
                    throw new Exception("如果订单状态服务者没有确认，不允许服务者确认预约");
                }
                order.status = (int)OrderStatus.ServiceConfirm;
                order.CooperationStartTime = confirmStartDate;
                order.CooperationEndTime = confirmEndDate;
            }


            //提醒消费者确认
            order.OrderRemind = GetOrderRemindByReminStatus(OrderRemindStatus.ConsumeCooperationConfirm);
            _orderDao.Update(order);
            return order;
        }

        public Order ConfirmOrderAsConsume(string orderNumber, string consumeUserName)
        {
            Order order = _orderDao.GetByOrderNumberAndConsumeUser(orderNumber, consumeUserName);

            if (order != null)
            {

                if ((OrderStatus)order.status != OrderStatus.ServiceConfirm)
                {
                    throw new Exception("如果订单状态服务者没有确认，不允许消费者确认预约");
                }
                order.status = (int)OrderStatus.ConsumeConfirm;
            }


            //提醒双方待评价
            order.OrderRemind = GetOrderRemindByReminStatus(OrderRemindStatus.RatingBoth);
            _orderDao.Update(order);

            return order;
        }


        public List<string> FindOrderNumbersByServiceInfoId(int serviceInfoId)
        {
            return _orderDao.FindOrderNumbersByServiceInfoId(serviceInfoId);
        }
    }
}
